package com.xoa.plugin;

import com.alibaba.fastjson.JSONArray;
import com.xoa.dao.WFE.WFEFormTypeMapper;
import com.xoa.dao.budget.BudgetingProcessMapper;
import com.xoa.dao.enclosure.AttachmentMapper;
import com.xoa.dao.workflow.FlowRunMapper;
import com.xoa.global.proxy.TriggerSubject;
import com.xoa.model.budget.BudgetingProcess;
import com.xoa.model.enclosure.Attachment;
import com.xoa.model.workflow.FlowFormType;
import com.xoa.model.workflow.FlowRun;
import com.xoa.model.workflow.TriggerPlugIn;
import com.xoa.service.rms.impl.RmsFileServiceImpl;
import com.xoa.util.GetAttachmentListUtil;
import com.xoa.util.ModuleEnum;
import com.xoa.util.common.StringUtils;
import com.xoa.util.dataSource.ContextHolder;
import com.xoa.util.netdisk.ZipUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 预算管理压缩附件
 * Created by Administrator on 2018/9/18.
 */
@Service
public class BudgetCompressTrigger implements TriggerSubject {

    @Resource
    private BudgetingProcessMapper budgetingProcessMapper;

    @Resource
    protected WFEFormTypeMapper wfeFormTypeMapper;

    @Resource
    private FlowRunMapper flowRunMapper;

    @Resource
    private AttachmentMapper attachmentMapper;

    @Resource
    private RmsFileServiceImpl rmsFileService;

    @Override
    public void doRun(String company, Object... ags) {
        ContextHolder.setConsumerType(company);
        TriggerPlugIn tri = (TriggerPlugIn) ags[0];

        Integer runId = Integer.valueOf(tri.getRunId());

        FlowRun flowRun = flowRunMapper.selectByRunId(runId);

        // 获取流程中的附件信息
        String attachmentName = flowRun.getAttachmentName();
        String attachmentId = flowRun.getAttachmentId();

        // 获取无数据的表单信息
        FlowFormType flowFormType = null;
        List<FlowFormType> frombyFlowId = wfeFormTypeMapper.getFrombyFlowId(Integer.valueOf(tri.getFlowId()));
        if (frombyFlowId != null && frombyFlowId.size() > 0) {
            flowFormType = frombyFlowId.get(0);
        }
        String htmlContent = flowFormType.getPrintModel();
        // 通过Jsoup插件解析成document对象（非公文的document对象）
        Document parse = Jsoup.parse(htmlContent);
        // 获取表单数据
        String formdata = tri.getModify();
        //表单上所有的数据
        List<Map<String, Object>> l = JSONArray.parseObject(formdata, List.class);
        //用来存储表单上所有的数据
        List<Map<String, Object>> lAll = new ArrayList<Map<String, Object>>();
        //处理异常数据,前台传入参数可能为空
        for (int i = 0; i < l.size(); i++) {
            if (l.get(i).size() == 2 && (String) l.get(i).get("key") != "") {
                lAll.add(l.get(i));
            }
        }
        // new一个存储表单中附件的集合  包括图片附件和普通附件
        List<String> formAttachments = new ArrayList<String>();
        // 循环获取到key和value 并赋值到元素上
        for (int i = 0, size = lAll.size(); i < size; i++) {
            Map<String, Object> map = lAll.get(i);
            Element data1 = parse.getElementById(String.valueOf(map.get("key")));
            // 判断是否是附件 如果是附件就把附件信息存储到附件集合中
            if (data1 != null) {
                if (data1.className().indexOf("upload") > 0) {
                    formAttachments.add(String.valueOf(map.get("value")));
                } else {
                    data1.val(String.valueOf(map.get("value")));
                }
            }
        }

        // 定义存储附件名称和附件id的变量
        StringBuilder formAttachmentNames = new StringBuilder();
        StringBuilder formAttachmentIds = new StringBuilder();
        // 循环遍历表单中的附件
        for (int i = 0, size = formAttachments.size(); i < size; i++) {
            String s = formAttachments.get(i);
            String[] split = s.split(",");
            for (int j = 0, length = split.length; j < length; j++) {
                String s1 = split[j];
                String[] split2 = s1.split("&");
                // 定义存储变量
                String aid = "";
                String ym = "";
                String attachId = "";
                String attachName = "";
                for (int k = 0, length2 = split2.length; k < length2; k++) {
                    String[] split3 = split2[k].split("=");
                    if (split3.length > 1) {
                        if (split3[0].toUpperCase().equals("AID")) {
                            aid = split3[1];
                        } else if (split3[0].toUpperCase().equals("YM")) {
                            ym = split3[1];
                        } else if (split3[0].toUpperCase().equals("ATTACHMENT_ID")) {
                            attachId = split3[1];
                        } else if (split3[0].toUpperCase().equals("ATTACHMENT_NAME")) {
                            attachName = split3[1];
                        }
                    }
                }
                if(!StringUtils.checkNull(aid)){
                    formAttachmentIds.append(aid).append("@").append(ym).append("_").append(attachId).append(",");
                    formAttachmentNames.append(attachName).append(",");
                }
            }
        }


        // 获取上传路径
        ResourceBundle rb = ResourceBundle.getBundle("upload");
        String os = System.getProperty("os.name");
        StringBuilder uploadHead = new StringBuilder();

        if (os.toLowerCase().startsWith("win")) {
            //判断路径是否是相对路径，如果是的话，加上运行的路径
            String uploadPath = rb.getString("upload.win");
            if (uploadPath.indexOf(":") == -1) {
                //获取运行时的路径
                String basePath = this.getClass().getClassLoader().getResource(".").getPath() + File.pathSeparator;
                //获取截取后的路径
                String str2 = "";
                if (basePath.indexOf("/xoa") != -1) {
                    //获取字符串的长度
                    int length = basePath.length();
                    //返回指定字符在此字符串中第一次出现处的索引
                    int index = basePath.indexOf("/xoa");
                    //从指定位置开始到指定位置结束截取字符串
                    str2 = basePath.substring(0, index);
                }
                uploadHead = uploadHead.append(str2 + "/xoa");
            }
            uploadHead.append(uploadPath);
            // 针对windows 在最前面添加盘符
            if(uploadHead.indexOf(":")==-1){
                String diskSymbol = new File("").getAbsolutePath().substring(0, 2);
                uploadHead.insert(0,diskSymbol);
            }
        } else {
            uploadHead = uploadHead.append(rb.getString("upload.linux"));
        }


        // 获取工作流flow_run中的附件信息 进行压缩打包
        List<Attachment> attachmentList = GetAttachmentListUtil.returnAttachment(attachmentName, attachmentId, company, "workflow");
        // 获取表单中的附件信息数组
        if (!StringUtils.checkNull(formAttachmentIds.toString()) && !StringUtils.checkNull(formAttachmentNames.toString())) {
            List<Attachment> attachmentList1 = GetAttachmentListUtil.returnAttachment(formAttachmentNames.toString(), formAttachmentIds.toString(), company, "workflow");
            attachmentList.addAll(attachmentList1);
        }
        // 要压缩的文件集合
        List<File> files = new ArrayList<File>();
        // 循环添加
        for (int i = 0, length = attachmentList.size(); i < length; i++) {
            Attachment attachment = attachmentList.get(i);
            StringBuilder flowFilePath = new StringBuilder(uploadHead.toString());
            flowFilePath.append(System.getProperty("file.separator")).
                    append(company).append(System.getProperty("file.separator")).
                    append("workflow").append(System.getProperty("file.separator")).append(attachment.getYm()).
                    append(System.getProperty("file.separator")).append(attachment.getAttachId()).append(".").append(attachment.getAttachName());
                            //append(System.getProperty("file.separator")).append(attachment.getAttachName());
            File file = new File(flowFilePath.toString());
            if(file.exists()){
                files.add(file);
            }
        }

        // 当前年月
        String ym = new SimpleDateFormat("yyMM").format(new Date());

        // 表单文件存储路径
        StringBuilder htmlFilePathBd = uploadHead;
        htmlFilePathBd.append(System.getProperty("file.separator")).
                append(System.getProperty("file.separator")).
                append(company).append(System.getProperty("file.separator")).
                append("workflow").append(System.getProperty("file.separator")).append(ym);

        // 表单文件路径地址
        String htmlFilePath = htmlFilePathBd.toString();
        // 生成表单文件目录
        boolean mkdirs = new File(htmlFilePath).mkdirs();

        // 压缩附件的日期前缀
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh：mm：ss ");
        Date date = new Date();
        String prifix = sdf.format(date);

        // 获得原始文件名
        String fileName = prifix + "预算表单.html";

        int attachID = Math.abs((int) System.currentTimeMillis());

        String newFileName = Integer.toString(attachID) + "." + fileName;

        // 生成文件
        String filePath = htmlFilePath + System.getProperty("file.separator") + newFileName;
        File formHtmlFile = new File(filePath);
        try {
            if (!formHtmlFile.exists()) {
                formHtmlFile.createNewFile();
            }
            // 表单内容写入到表单文件中
            OutputStreamWriter pw = new OutputStreamWriter(new FileOutputStream(filePath), "UTF-8");
            pw.write("<html><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"></head>");
            pw.write(rmsFileService.HTML_STYLE);
            pw.write("<body>");
            pw.write(parse.toString());
            pw.write("</body></html>");
            pw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //获得模块id
        byte mid = 0;
        for (ModuleEnum em : ModuleEnum.values()) {
            if (em.getName().equals("workflow")) {
                mid = (byte) em.getIndex();
            }
        }

        // 把表单添加到要压缩的集合中
        files.add(formHtmlFile);
        // 生成压缩包地址
        String zipPath = filePath.replace("预算表单.html", "预算附件.zip");

        /*上分割线*/
        // TODO 临时：为确保生成zip文件修改路径
        // TODO 本地和服务器上的上传路径不同...
        // 注：ZipUtils.zipFiles使用绝对路径
        // 获得盘符
        if (os.toLowerCase().startsWith("win")) {
            String diskSymbol = new File("").getAbsolutePath().substring(0, 2);
            // 路径中不包含：认为是相对路径
            if (!zipPath.contains(":")) {
                zipPath = diskSymbol + zipPath;
            }
        }
        /*下分割线*/

        ZipUtils.zipFiles(files, zipPath);
        // 获取zipFile
        File zipFile = new File(zipPath);
        // 如果文件不存在
        if (zipFile.exists()) {
            fileName = prifix + "预算附件.zip";
            // 保存进数据库
            Attachment attachment = new Attachment();
            attachment.setAttachId(String.valueOf(attachID));
            attachment.setModule(mid);
            attachment.setAttachFile(fileName);
            attachment.setAttachName(fileName);
            attachment.setYm(ym);
            attachment.setAttachSign(new Long(0));
            attachment.setDelFlag((byte) 0);
            attachment.setPosition((byte) 2);
            attachment.setIsImage((byte) 0);
            attachment.setFileSize(String.valueOf(formHtmlFile.length()));
            attachment.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

            attachmentMapper.insertSelective(attachment);

            // 更新附件信息
            BudgetingProcess budgetingProcess = new BudgetingProcess();
            budgetingProcess.setZipAttachmentId(attachment.getAid() + "@" + attachment.getYm() + "_" + attachment.getAttachId());
            budgetingProcess.setZipAttachmentName(attachment.getAttachName());
            budgetingProcess.setRunId(runId);
            budgetingProcessMapper.updateAttachmentByRunId(budgetingProcess);
        }
    }

}
